package com.practice.niuke.new_direct_basics.class08;

/**
 * 规定1和A对应、 2和B对应、 3和C对应...
 * 那么一个数字字符串比如"111"， 就可以转化为"AAA"、 "KA"和"AK"。
 * 给定一个只有数字字符组成的字符串str， 返回有多少种转化结果。
 */
public class Code06_ConvertToLetterString {

    /**
     * 主函数（TODO：标记主函数）
     *
     * @param str
     * @return
     */
    public static int number(String str) {
        if (str == null || str.length() == 0) {
            return 0;
        }
        // 调用递归函数
        return process(str.toCharArray(), 0);
    }

    // i之前的位置，如何转化已经做过决定了, 不用再关心。
    // str[i...] 有多少种转化的结果
    public static int process(char[] str, int i) {
        if (i == str.length) { // base case
            // i来到终止位置时，之前做的所有决定的路径是1种有效的转换方法
            return 1;
        }
        // i没有到终止位置，但是当前字符为‘0’字符
        if (str[i] == '0') {
            return 0;
        }
        // str[i]字符不是‘0’
        if (str[i] == '1') {
            int res = process(str, i + 1); // i自己作为单独的部分，后续有多少种方法
            if (i + 1 < str.length) {
                res += process(str, i + 2); // (i和i+1)作为单独的部分，后续有多少种方法
            }
            return res;
        }
        if (str[i] == '2') {
            int res = process(str, i + 1); // i自己作为单独的部分，后续有多少种方法
            // (i和i+1)作为单独的部分并且没有超过26，后续有多少种方法
            if (i + 1 < str.length && (str[i + 1] >= '0' && str[i + 1] <= '6')) {
                res += process(str, i + 2); // (i和i+1)作为单独的部分，后续有多少种方法
            }
            return res;
        }
        // str[i] == '3' ~ '9'
        return process(str, i + 1);
    }

    public static void main(String[] args) {
        System.out.println(number("11111"));
    }

}
